# ----------------------------------------------------------------------------
#       Copyright (C) 2013-2014 Huynh Vi Lam  <domovilam@gmail.com>
#
#       This file is part of pimucha.
#
#	This program is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#	
#	This program is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#	
#	You should have received a copy of the GNU General Public License
#	along with this program.  If not, see <http://www.gnu.org/licenses/>.
# ----------------------------------------------------------------------------

import logging,datetime,sys
if sys.hexversion > 0x030000F0:
    import queue as Queue
else:
    import Queue
QEmpty = Queue.Empty

from functools import wraps
from .conflibs import (confgetval,confgetint)
from .sqlitedb import (majdb3,fieldsdb3)

logger = logging.getLogger()

def coroutine(func):
    def start(*args,**kwargs):
        cr = func(*args,**kwargs)
        next(cr)
        return cr
    return start

def my_fctname(f):
    @wraps(f)
    def wrapper(*args, **kwds):
        return f(*args, **kwds)
    return wrapper


@coroutine
def broadcast(targets):
    while True:
        line = (yield)
        for target in targets:
            target.send(line)


@my_fctname
@coroutine
def debug():
    while True:
        msg = (yield)
        logger.debug(repr(msg))


@coroutine
def evtputinq(evtq):
    logger.debug("Queue %s", repr(evtq))
    while True:
        evt = (yield)
        logger.debug("Event %s",repr(evt))
        try:
            evtq.put_nowait(evt)
            logger.debug("%s events in queue %s",str(evtq.qsize()),repr(evtq))
        except:
            pass


@coroutine
def evt2netq(netq):
    logger.debug("Queue %s", repr(netq))
    while True:
        evt = (yield)
        if isinstance(evt,list):
            data = '|'.join(evt)
        else:
            data = evt
        logger.debug("Event %s",repr(data))
        try:
            netq.put(data)
            logger.debug("%s events in queue %s",str(netq.qsize()),repr(netq))
        except:
            pass


@coroutine
def filterevt(target,filter=None):
    lasttime = datetime.datetime.today()
    evtfilter = confgetval('pimucha.conf',filter,'EVTFilter',None)
    evtdelay = confgetint('pimucha.conf',filter,'EVTDelay',0)
    while True:
        event = (yield)
        now = datetime.datetime.today()            
        if evtfilter:
            if event[1].startswith(evtfilter):
                t = lasttime + datetime.timedelta(seconds=evtdelay)
                if t > now:
                    logger.debug("Event filter in repeat delay")
                    lasttime = now
                    continue
        target.send(event)


@coroutine
def raw2netq(netq):
    logger.debug("Queue %s", repr(netq))
    while True:
        evt = (yield)
        logger.debug("Event %s",repr(evt))
        if isinstance(evt,list):
            data = evt[1]
        else:
            data = evt
        try:
            netq.put(data)
            logger.debug("%s events in queue %s",str(netq.qsize()),repr(netq))
        except:
            pass


@coroutine
def log2file(logfile,sep=" "):
    while True:
       	msg = (yield)
        if sep == '':
            line = msg
        else:
            line = sep.join([str(i) for i in msg])
        try:
            wf = open(logfile,'ab')
            wf.write((line + "\n").encode('utf-8'))
            wf.close()
        except Exception as e:
            logger.error("%s : %s", repr(e.__class__), str(e))


@coroutine
def log2db(tablename='decodedevents'):
    while True:
        item = (yield)
        nbi = len(item)
        fields = fieldsdb3(tablename)
        #Discard first field rowId
        fields = fields[1:]
        nbf = len(fields)
        req = 'INSERT INTO ' + tablename + '('
        V = ' VALUES ('
        lenreq = nbf
        #Value for the last field
        if nbi > nbf:	#more items than fields, concatenate last items
            item = item[:nbf-1] + [' '.join(item[nbf-1:])]
        elif nbi < nbf:
            lenreq = nbi
        #Generate request
        for i in range(0,lenreq):
            req += fields[i] + ','
            V += '?,'
        #End of request
        V = V[:-1] + ');'
        req = req[:-1] + ') ' + V
        majdb3(req,item)


@coroutine
def multievtqueue(mcrx=None):
    while True:
        evt = (yield)
        if mcrx:
            mcrx.multievtq.put_nowait(evt)
        else:
            print (repr(evt))


@coroutine
def printer():
    while True:
        msg = (yield)
        print (repr(msg))


@coroutine
def unduplicate(target,ellapse=10):
    lastevt = None
    lasttime = datetime.datetime.today()
    while True:
        event = (yield)
        now = datetime.datetime.today()            
        if event == lastevt:
            t = lasttime + datetime.timedelta(seconds=ellapse)
            if t > now:
                logger.debug("Event in repeat delay")
                lasttime = now
                continue
        target.send(event)
        lastevt = event
        lasttime = now
